//这个部分优化then方法，
const PROMISE_STATUS_PENDING = "pending"
const PROMISE_STATUS_FULFILLED = "fulfilled"
const PROMISE_STATUS_REJECTED = "rejected"

// 工具函数
function execFunctionWithCatchError(execFn, value, resolve, reject) {
  try {
    const result = execFn(value)
    resolve(result)
  } catch (error) {
    reject(error)
  }
}

class XJPromise {
  // 构造函数方法
  constructor(executor) {
    // 刚进入的时候当前状态
    this.status = PROMISE_STATUS_PENDING
    this.value = undefined //用于保存resolve的参数值，用于then方法中的回调显示
    this.reason = undefined
    this.onfulfilledFunctions = [] //用来保存多次成功的调用
    this.onrejectedFunctions = [] //用来保存多次失败的调用

    const resolve = (value) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        queueMicrotask(() => {
          //通过setTimeOut，让这段代码进入宏任务队列，这样，then方法就可以先执行了，不然调用then中的回调，
          // then方法都不存在呢，更别说then方法中的回调调用了，但是setTimeout是宏任务，所以改一下，用queueMicrotask
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status === PROMISE_STATUS_FULFILLED
          this.reason = value
          //接下来应该调用then传递过来的回调函数
          // 遍历执行
          this.onfulfilledFunctions.forEach((fn) => {
            let value = fn(this.value)
          })
        })
      }
    }
    const reject = (reason) => {
      if (this.status === PROMISE_STATUS_PENDING) {
        queueMicrotask(() => {
          if (this.status !== PROMISE_STATUS_PENDING) return
          this.status === PROMISE_STATUS_REJECTED
          this.reason = reason
          // 调用失败时then传递过来的回调函数
          // 遍历执行
          this.onrejectedFunctions.forEach((fn) => {
            let reason = fn(this.value)
          })
        })
      }
    }
    try {
      executor(resolve, reject) //执行器函数直接调用
    } catch (error) {
      reject(error)
    }
  }

  //实例方法- then方法
  then(onfulfilled, onrejected) {
    // 用于catch方法和finally方法
    const defaultOnReject = (err) => {
      throw err
    }
    onrejected = onrejected || defaultOnReject

    const defaultOnResolve = (value) => {
      return value
    }
    onfulfilled = onfulfilled || defaultOnResolve

    //返回一个新的promise
    return new XJPromise((resolve, reject) => {
      // 1.情况1,如果调用then状态未确定
      if (this.status === PROMISE_STATUS_PENDING) {
        if (onfulfilled) {
          this.onfulfilledFunctions.push(() => {
            // try {
            //   const value = onfulfilled(this.value)
            //   resolve(value)
            // } catch (error) {
            //   reject(error)
            // }
            execFunctionWithCatchError(onfulfilled, this.value, resolve, reject)
          })
        }
        if (onrejected) {
          this.onrejectedFunctions.push(() => {
            // try {
            //   const reason = onrejected(this.reason)
            //   resolve(reason)
            // } catch (error) {
            //   reject(error)
            // }
            execFunctionWithCatchError(onrejected, this.reason, resolve, reject)
          })
        }
      }
      //2.如果再then调用的时候，状态已经确定下来
      if (this.status === PROMISE_STATUS_FULFILLED && onfulfilled) {
        // try {
        //   const value = onfulfilled(this.value)
        //   resolve(value)
        // } catch (error) {
        //   reject(error)
        // }
        execFunctionWithCatchError(onfulfilled, this.value, resolve, reject)
      }

      if (this.status === PROMISE_STATUS_REJECTED && onrejected) {
        // try {
        //   const reason = onrejected(this.value)
        //   resolve(reason)
        // } catch (error) {
        //   reject(error)
        // }
        execFunctionWithCatchError(onrejected, this.reason, resolve, reject)
      }
    })
  }

  // catch方法
  catch(onrejected) {
    return this.then(undefined, onrejected)
  }

  // finally方法
  finally(onFinally) {
    this.then(
      () => {
        onFinally()
      },
      () => {
        onFinally()
      }
    )
  }

  // 类方法
  static resolve(value) {
    return new XJPromise((resolve) => resolve(value))
  }
  static reject(reason) {
    return new XJPromise((reason) => this.reject(reason))
  }

  // all allsettled
  static all(promises) {
    // 问题关键：什么时候执行resolve，什么时候执行reject
    return new XJPromise((resolve, reject) => {
      const values = []
      promises.forEach((pro) => {
        pro.then(
          (res) => {
            values.push(res)
            if (values.length === pro.length) {
              resolve(values)
            }
          },
          (err) => {
            reject(err)
          }
        )
      })
    })
  }

  static allSettled(promises) {
    return new XJPromise((resolve) => {
      const results = []
      promises.forEach((pro) => {
        pro.then(
          (res) => {
            results.push({ status: PROMISE_STATUS_FULFILLED, value: res })
            if (results.length === promises.length) {
              resolve(results)
            }
          },
          (err) => {
            results.push({ status: PROMISE_STATUS_REJECTED, value: err })
            if (results.length === promises.length) {
              resolve(results)
            }
          }
        )
      })
    })
  }
}

// 调用
const promise = new XJPromise((resolve, reject) => {
  console.log("当前还处于pending状态")
  // resolve("resolve")
  reject("失败回调")
}).then(
  (res) => {
    console.log("res", res)
  },
  (err) => {
    console.log("err", err)
  }
)

setTimeout(() => {
  promise.then((res) => {
    console.log("fdafd")
  })
}, 3000)
